package com.example.maze.model;

/**
 * 迷宫单元格类，表示迷宫中的一个格子
 * 
 * @author maze-demo
 */
public class Cell {
    /**
     * 单元格类型枚举
     */
    public enum Type {
        WALL,    // 墙
        PATH,    // 通路
        START,   // 起点
        END,     // 终点
        VISITED, // 已访问（用于寻路可视化）
        SOLUTION, // 解路径（用于显示最终路径）
        DFS_PATH,  // DFS算法路径
        BFS_PATH,  // BFS算法路径
        ASTAR_PATH // A*算法路径
    }

    private Type type;
    private final Coordinate coordinate;
    
    // 用于寻路算法的辅助字段
    private boolean visited;
    private Cell parent;
    private int gCost; // A*算法中的g值（从起点到当前点的实际代价）
    private int hCost; // A*算法中的h值（启发式估计值）
    
    public Cell(Coordinate coordinate, Type type) {
        this.coordinate = coordinate;
        this.type = type;
        this.visited = false;
        this.parent = null;
        this.gCost = 0;
        this.hCost = 0;
    }

    public Cell(int row, int col, Type type) {
        this(new Coordinate(row, col), type);
    }

    // Getters and Setters
    public Type getType() {
        return type;
    }

    public void setType(Type type) {
        this.type = type;
    }

    public Coordinate getCoordinate() {
        return coordinate;
    }

    public boolean isVisited() {
        return visited;
    }

    public void setVisited(boolean visited) {
        this.visited = visited;
    }

    public Cell getParent() {
        return parent;
    }

    public void setParent(Cell parent) {
        this.parent = parent;
    }

    public int getGCost() {
        return gCost;
    }

    public void setGCost(int gCost) {
        this.gCost = gCost;
    }

    public int getHCost() {
        return hCost;
    }

    public void setHCost(int hCost) {
        this.hCost = hCost;
    }

    /**
     * 计算A*算法中的f值 (f = g + h)
     */
    public int getFCost() {
        return gCost + hCost;
    }

    /**
     * 检查是否可以通过（不是墙）
     */
    public boolean isPassable() {
        return type != Type.WALL;
    }

    /**
     * 重置单元格状态（用于多次寻路）
     */
    public void reset() {
        this.visited = false;
        this.parent = null;
        this.gCost = 0;
        this.hCost = 0;
        // 保持原有类型，但清除寻路相关的类型
        if (type == Type.VISITED || type == Type.SOLUTION || 
            type == Type.DFS_PATH || type == Type.BFS_PATH || type == Type.ASTAR_PATH) {
            type = Type.PATH;
        }
    }

    @Override
    public String toString() {
        return String.format("Cell[%s, %s]", coordinate, type);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Cell cell = (Cell) obj;
        return coordinate.equals(cell.coordinate);
    }

    @Override
    public int hashCode() {
        return coordinate.hashCode();
    }
}